#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@File   : test04_login_and_desktop.py
@Time : 2025/1/6 15:36
@Author: Wangwc
@Describe:  ……
"""
import random
import warnings

import requests
from urllib3.exceptions import InsecureRequestWarning

warnings.filterwarnings("ignore", category=InsecureRequestWarning)

import time
import allure
import pytest

from business.CloudApi import CloudApi
from business.LoginApi import LoginApi
from business.SystemApi import SystemApi
from utils.encrypt_tools import DataEncrypt
from utils.login import Login
from commons.logger import log
from utils.config_tools import Config
from commons.fake_data import Fake


# TODO 当前模块的配置文件名称，配置在config目录下
config_name = "cloud.ini"
login = Login(config_name=config_name)
config = Config(config_name=config_name)

@pytest.fixture(scope="function")
def api():
    """
    用于初始化LoginApi客户端的夹具，不带token
    """
    return LoginApi(config_name=config_name)

@pytest.fixture(scope="function")
def cloud_api():
    """
    用于初始化CloudApi客户端的夹具，不带token
    """
    return CloudApi(config_name=config_name)

global_token = None

@pytest.fixture(scope="function")
def init_api():
    global global_token
    if global_token is None:
        global_token = login.login()
    api = SystemApi(global_token, configname=config_name)
    return api


def handle_api_call(api_method, *args, attach_to_allure=True, format_result=None, **kwargs):
    if not callable(api_method):
        raise TypeError("api_method 参数必须是可调用对象（如函数或方法）")
    if attach_to_allure is not None and not isinstance(attach_to_allure, bool):
        raise TypeError("attach_to_allure 参数必须是布尔类型或者为 None")
    if format_result is not None and not callable(format_result):
        raise TypeError("format_result 参数必须是可调用对象（如函数）或者为 None")

    max_retries = 3
    for retry in range(max_retries):
        try:
            result = api_method(*args, **kwargs)
            if attach_to_allure:
                if format_result:
                    formatted_result = format_result(result)
                else:
                    formatted_result = str(result)
                allure.attach(formatted_result, f"{api_method.__name__} 调用结果", allure.attachment_type.TEXT)
            log.info(f"{api_method.__name__} 调用成功")
            return result
        except Exception as e:
            allure.attach(str(e), f"{api_method.__name__} 调用错误信息", allure.attachment_type.TEXT)
            log.error(f"{api_method.__name__} 调用出现错误: {e}", exc_info=True)
            # 假设根据错误信息判断 token 过期
            if "token 过期" in str(e) and retry < max_retries - 1:
                global global_token
                global_token = login.login()
                api_method.__self__.token = global_token
                continue
            elif isinstance(e, ConnectionError):
                log.error("连接错误，可能是网络问题，请检查网络连接。")
            elif isinstance(e, ValueError):
                log.error("值错误，可能是传入的参数有误，请检查参数。")
            raise

@allure.feature("登录&桌面")
class TestLoginAndDeskTop():
    @pytest.mark.skip(reason = "跳过，需要满足jenkins服务器与NAS设备在同一个局域网")
    @allure.title("Find-搜索到局域网内设备并连接成功")
    def test_find_device_and_login(self, api):
        with allure.step("获取当前局域网内所有设备信息"):
            device_list = handle_api_call(api.get_devices)
            assert device_list != [], "获取外接设备信息失败"

        with allure.step("读取配置文件中设备sn"):
            sn = config.read_config_ini('device', 'device_sn')
            hostname = config.read_config_ini('envHost', 'hostname')
            username = config.read_config_ini('user', 'user_name')
            log.info(f"读取配置文件中设备sn: {sn}")

        with allure.step("确定设备"):
            device = handle_api_call(api.get_device,sn, device_list)
            device_ip = device.get('ipv4')
            assert hostname == device_ip, f"设备ip与配置文件中ip不一致，预期ip为：{hostname}，实际ip为：{device_ip}"

        with allure.step("使用http+端口9999登录设备"):
            Rsa_token = handle_api_call(api.general_verify_check,device_ip)
            time.sleep(0.5)
            login_info = handle_api_call(api.general_login,device_ip,Rsa_token)
            user = login_info.get('username')
            assert user == username, f"登录设备失败，预期用户名为：{username}，实际用户名为：{user}"

    @allure.title("IPV4网络 http登录")
    def test_login_with_ipv4_http(self, api):
        with allure.step("获取登录前的基本信息"):
            host_name = config.read_config_ini('envHost', 'hostname')
            user_name = config.read_config_ini('user', 'user_name')
            log.info(f"获取到的设备IP基本信息为: {host_name}，登录用户为：{user_name}")

        with allure.step("获取Rsa_token"):
            Rsa_token = handle_api_call(api.general_verify_check, host_name)
            time.sleep(0.5)


        with allure.step("使用http+端口9999登录设备"):
            login_info = handle_api_call(api.general_login, host_name, Rsa_token)
            user = login_info.get('username')
            assert user == user_name, f"登录设备失败，预期用户名为：{user_name}，实际用户名为：{user}"

    @allure.title("IPV4网络 https登录")
    def test_login_with_ipv4_https(self, api):
        with allure.step("获取登录前的基本信息"):

            host_name = config.read_config_ini('envHost', 'hostname')
            user_name = config.read_config_ini('user', 'user_name')
            log.info(f"获取到的设备IP基本信息为: {host_name}，登录用户为：{user_name}")

        with allure.step("获取Rsa_token"):
            Rsa_token = handle_api_call(api.general_verify_check, host_name,protocol='https',port=9443)
            time.sleep(0.5)

        with allure.step("使用http+端口9999登录设备"):
            login_info = handle_api_call(api.general_login, host_name, Rsa_token,protocol='https',port=9443)
            user = login_info.get('username')
            assert user == user_name, f"登录设备失败，预期用户名为：{user_name}，实际用户名为：{user}"

    @allure.title("自定义https端口登录")
    def test_login_with_defined_https_port(self, api, init_api):
        with allure.step("获取网页服务端口"):
            host_name = config.read_config_ini('envHost', 'hostname')
            user_name = config.read_config_ini('user', 'user_name')
            log.info(f"获取到的设备IP基本信息为: {host_name}，登录用户为：{user_name}")
            ports = handle_api_call(init_api.get_nginx_connect, host_name, protocol='https', port="9443")
            assert ports.get('https') == 9443, f"获取到的https端口为：{ports.get('https')}，预期为：9443"

        with allure.step("设置新的网页服务端口"):
            new_https_port = random.randint(9000, 9442)
            handle_api_call(init_api.set_nginx_connect, host_name, protocol='https', port="9443",
                            https_port=new_https_port)
            time.sleep(0.5)

        with allure.step("确认网页服务端口修改成功"):
            new_ports = handle_api_call(init_api.get_nginx_connect, host_name)
            assert new_ports.get('https') == new_https_port, f"获取到的https端口为：{ports.get('https')}，预期为：{new_https_port}"

        with allure.step("使用新端口获取Rsa_token"):
            Rsa_token = handle_api_call(api.general_verify_check, host_name,protocol='https', port=new_https_port)
            time.sleep(0.5)

        with allure.step("使用https+新端口登录设备"):
            login_info = handle_api_call(api.general_login, host_name, Rsa_token,protocol='https', port=new_https_port)
            user = login_info.get('username')
            assert user == user_name, f"登录设备失败，预期用户名为：{user_name}，实际用户名为：{user}"

    @allure.title("自定义http端口登录")
    def test_login_with_defined_http_port(self, api,init_api):
        with allure.step("获取网页服务端口"):
            host_name = config.read_config_ini('envHost', 'hostname')
            user_name = config.read_config_ini('user', 'user_name')
            log.info(f"自定义http端口登录获取到的设备IP基本信息为: {host_name}，登录用户为：{user_name}")
            ports = handle_api_call(init_api.get_nginx_connect,host_name)
            log.info(f"自定义http端口获取到的网页服务端口为：{ports.get('http')}")
            assert ports.get('http') == 9999, f"获取到的http端口为：{ports.get('http')}，预期为：9999"

        with allure.step("设置新的网页服务端口"):
            new_http_port = random.randint(9500, 9998)
            handle_api_call(init_api.set_nginx_connect,host_name,http_port=new_http_port)
            time.sleep(0.5)

        with allure.step("确认网页服务端口修改成功"):
            new_ports = handle_api_call(init_api.get_nginx_connect,host_name,port=new_http_port)
            assert new_ports.get('http') == new_http_port, f"获取到的http端口为：{ports.get('http')}，预期为：{new_http_port}"

        with allure.step("使用新端口获取Rsa_token"):
            Rsa_token = handle_api_call(api.general_verify_check, host_name,port=new_http_port)
            time.sleep(0.5)

        with allure.step("使用http+新端口登录设备"):
            login_info = handle_api_call(api.general_login, host_name, Rsa_token,port=new_http_port)
            user = login_info.get('username')
            assert user == user_name, f"登录设备失败，预期用户名为：{user_name}，实际用户名为：{user}"

        with allure.step("恢复默认端口"):
            handle_api_call(init_api.set_nginx_connect, host_name, port=new_http_port)
            time.sleep(0.5)
            new_ports = handle_api_call(init_api.get_nginx_connect, host_name)
            assert new_ports.get('http') == 9999, f"获取到的https端口为：{ports.get('http')}，预期为：9999"
            assert new_ports.get('https') == 9443, f"获取到的https端口为：{ports.get('https')}，预期为：9443"

    @allure.title("使用ddns带http登录")
    def test_login_with_ddns_http(self, api, init_api):
        with allure.step("获取ddns等登录信息"):
            user_name = config.read_config_ini('user', 'user_name')
            port = config.read_config_ini('ddns', 'http_port')   # 这个是手动映射时绑定的外部端口
            log.info(f"获取到的设备IP基本信息为:登录用户为：{user_name}")
            ddns_list = handle_api_call(init_api.get_ddns_list)
            ddns = ddns_list[0].get('domain')
            assert ddns != '', f"获取到的ddns列表为：{ddns}，预期不为空"

        with allure.step("使用新端口获取Rsa_token"):
            Rsa_token = handle_api_call(api.general_verify_check, ddns, protocol='http', port=port)
            time.sleep(0.5)

        with allure.step("使用https+新端口登录设备"):
            login_info = handle_api_call(api.general_login, ddns, Rsa_token, protocol='http', port=port)
            user = login_info.get('username')
            assert user == user_name, f"登录设备失败，预期用户名为：{user_name}，实际用户名为：{user}"

    @allure.title("使用ddns带https登录")
    def test_login_with_ddns_https(self, api, init_api):
        with allure.step("获取ddns等登录信息"):
            user_name = config.read_config_ini('user', 'user_name')
            port = config.read_config_ini('ddns', 'https_port')          # 这个是手动映射时绑定的外部端口
            log.info(f"获取到的设备IP基本信息为:登录用户为：{user_name}")
            ddns_list = handle_api_call(init_api.get_ddns_list)
            ddns = ddns_list[0].get('domain')
            assert ddns != '', f"获取到的ddns列表为：{ddns}，预期不为空"

        with allure.step("使用新端口获取Rsa_token"):
            Rsa_token = handle_api_call(api.general_verify_check, ddns, protocol='https', port=port)
            time.sleep(0.5)

        with allure.step("使用https+新端口登录设备"):
            login_info = handle_api_call(api.general_login, ddns, Rsa_token, protocol='https', port=port)
            user = login_info.get('username')
            assert user == user_name, f"登录设备失败，预期用户名为：{user_name}，实际用户名为：{user}"

    @allure.title("解绑云端账号")
    def test_ubind_cloud_account(self, init_api, cloud_api):
        with allure.step("获取云端账号绑定信息"):
            user_name = config.read_config_ini('user', 'user_name')
            uid = handle_api_call(init_api.get_user_uid, user_name)
            cloud_info = handle_api_call(init_api.is_bind, uid)
            assert cloud_info.get('ugreenNo') != None, f"获取到的绑定信息为：{cloud_info}，预期为已绑定"

        with allure.step("获取云端密钥"):
            result = handle_api_call(cloud_api.get_encrypt_key)
            uuid = result.get('uuid')
            encryptKey = result.get('encryptKey')

        with allure.step("云端登录数据准备"):
            raw_user_name = config.read_config_ini('cloud', 'user_name')
            raw_password = config.read_config_ini('cloud', 'user_pwd')
            deviceSn = config.read_config_ini('device', 'device_sn')

        with allure.step("登录云端账号"):
            cloud_user_name = DataEncrypt.aes_encrypt(encryptKey, uuid, raw_user_name)
            cloud_password = DataEncrypt.aes_encrypt(encryptKey, uuid, raw_password)
            data = handle_api_call(cloud_api.get_cloud_token, cloud_user_name, cloud_password, uuid)
            acces_token = data.get('accessToken').get('access_token')

        with allure.step("解绑云端账号"):
            # handle_api_call(cloud_api.send_code, acces_token, uuid)
            # time.sleep(3)
            handle_api_call(cloud_api.app_unbind_device, acces_token, deviceSn)
            time.sleep(3)

        with allure.step("再次获取云端账号绑定信息"):
            cloud_info = handle_api_call(init_api.is_bind, uid)
            assert cloud_info.get('ugreenNo') == 0, f"获取到的绑定信息为：{cloud_info}，预期为未绑定"

    @allure.title("绑定云端账号")
    def test_bind_cloud_account(self, init_api, cloud_api):
        with allure.step("获取云端账号绑定信息"):
            user_name = config.read_config_ini('user', 'user_name')
            uid = handle_api_call(init_api.get_user_uid, user_name)
            cloud_info = handle_api_call(init_api.is_bind, uid)
            assert cloud_info.get('ugreenNo') == False, f"获取到的绑定信息为：{cloud_info}，预期为未绑定"

        with allure.step("获取云端密钥"):
            result = handle_api_call(cloud_api.get_encrypt_key)
            uuid = result.get('uuid')
            encryptKey = result.get('encryptKey')

        with allure.step("云端登录数据准备"):
            raw_user_name = config.read_config_ini('cloud', 'user_name')
            raw_password = config.read_config_ini('cloud', 'user_pwd')

        with allure.step("云端登录数据加密"):
            cloud_user_name = DataEncrypt.aes_encrypt(encryptKey, uuid, raw_user_name)
            cloud_password = DataEncrypt.aes_encrypt(encryptKey, uuid, raw_password)
            data = handle_api_call(cloud_api.get_cloud_token, cloud_user_name, cloud_password, uuid)
            acces_token = data.get('accessToken').get('access_token')
            ugreen_no = data.get('user').get('ugreenNo')

        with allure.step("绑定云端账号"):
            handle_api_call(init_api.cloud_bind, ugreen_no, acces_token)
            time.sleep(3)

        with allure.step("再次获取云端账号绑定信息"):
            cloud_info = handle_api_call(init_api.is_bind, uid)
            assert cloud_info.get('ugreenNo') == ugreen_no, f"获取到的绑定信息为：{cloud_info}，预期为已绑定"

        with allure.step("开启uglink"):
            uglink_info = handle_api_call(init_api.get_uglink_status)
            alias = uglink_info.get('alias')
            handle_api_call(init_api.enable_uglink, alias)

    @allure.title("uglink url登录")
    def test_login_with_uglink_url(self, api, init_api):
        with allure.step("获取uglink id等登录信息"):
            user_name = config.read_config_ini('user', 'user_name')
            uglink_info = handle_api_call(init_api.get_uglink_status)
            internalDomain = uglink_info.get('internalDomain')
            assert internalDomain != '', f"获取到的uglink_info为：{uglink_info}，预期不为空"

        with allure.step("使用uglink url获取Rsa_token"):
            host = internalDomain.rstrip(':8088')
            Rsa_token = handle_api_call(api.general_verify_check, host, protocol='https', port=8088)
            time.sleep(0.5)

        with allure.step("使用https+新端口登录设备"):
            login_info = handle_api_call(api.general_login, host, Rsa_token, protocol='https', port=8088)
            user = login_info.get('username')
            assert user == user_name, f"登录设备失败，预期用户名为：{user_name}，实际用户名为：{user}"

    @allure.title("uglink id登录")
    def test_login_with_uglink_id(self, api, init_api):
        with allure.step("获取uglink id等登录信息"):
            user_name = config.read_config_ini('user', 'user_name')
            cloud_host = config.read_config_ini('cloud', 'host')
            uglink_info = handle_api_call(init_api.get_uglink_status)
            uglink_id = uglink_info.get('alias')
            internalDomain = uglink_info.get('internalDomain')
            assert uglink_id != '' and internalDomain != '', f"获取到的uglink_info为：{uglink_info}，预期不为空"

        with allure.step("根据uglink id 获取节点信息"):
            cloud_info = handle_api_call(init_api.get_uglink_nodeInfo_byAlias, cloud_host, uglink_id)
            assert cloud_info.get('alias') == uglink_id, f"获取到的节点id信息为：{cloud_info}，预期节点id为：{uglink_id}"

        with allure.step("使用uglink id获取Rsa_token"):
            host = internalDomain.rstrip(':8088')
            Rsa_token = handle_api_call(api.general_verify_check, host, protocol='https', port=8088)
            time.sleep(0.5)

        with allure.step("使用https+新端口登录设备"):
            login_info = handle_api_call(api.general_login, host, Rsa_token, protocol='https', port=8088)
            user = login_info.get('username')
            assert user == user_name, f"登录设备失败，预期用户名为：{user_name}，实际用户名为：{user}"


    # @pytest.mark.skip(reason="跳过，需要满足jenkins服务器与NAS设备在同一个局域网")
    # @allure.title("自定义域名http登录")
    # def test_login_with_domain_http(self, api, init_api):
    #     with allure.step("设置域名信息"):
    #         user_name = config.read_config_ini('user', 'user_name')
    #         domain_name = Fake.fake_domain()
    #         log.info(f"设置域名信息为：{domain_name}，数据类型为{type(domain_name)}")
    #         handle_api_call(init_api.set_domain,domain_name)
    #
    #     with allure.step("再次获取域名信息"):
    #         new_domain_info = handle_api_call(init_api.get_domain)
    #         new_domain_name = new_domain_info.get('name')
    #         log.info(f"获取的新域名为{new_domain_name}，数据类型为{type(new_domain_name)}")
    #         assert new_domain_name == domain_name.lower(), f"设置域名失败，预期域名：{domain_name}，实际域名：{new_domain_name}"
    #
    #     with allure.step("使用自定义域名获取Rsa_token"):
    #         Rsa_token = handle_api_call(api.general_verify_check, new_domain_name)
    #
    #     with allure.step("使用自定义域名登录设备"):
    #         login_info = handle_api_call(api.general_login, new_domain_name, Rsa_token)
    #         user = login_info.get('username')
    #         assert user == user_name, f"登录设备失败，预期用户名为：{user_name}，实际用户名为：{user}"
    #
    # @pytest.mark.skip(reason="跳过，需要满足jenkins服务器与NAS设备在同一个局域网")
    # @allure.title("自定义域名https登录")
    # def test_login_with_domain_https(self, api, init_api):
    #     with allure.step("设置域名信息"):
    #         user_name = config.read_config_ini('user', 'user_name')
    #         domain_name = Fake.fake_domain()
    #         handle_api_call(init_api.set_domain, domain_name)
    #
    #     with allure.step("再次获取域名信息"):
    #         new_domain_info = handle_api_call(init_api.get_domain)
    #         new_domain_name = new_domain_info.get('name')
    #         assert new_domain_name == domain_name.lower(), f"设置域名失败，预期域名：{domain_name}，实际域名：{new_domain_name}"
    #
    #     with allure.step("使用自定义域名获取Rsa_token"):
    #         Rsa_token = handle_api_call(api.general_verify_check, new_domain_name, protocol='https',port=9443)
    #
    #     with allure.step("使用自定义域名登录设备"):
    #         login_info = handle_api_call(api.general_login, new_domain_name, Rsa_token, protocol='https',port=9443)
    #         user = login_info.get('username')
    #         assert user == user_name, f"登录设备失败，预期用户名为：{user_name}，实际用户名为：{user}"

    @allure.title("获取账号活动记录")
    def test_get_user_history(self, init_api):
        with allure.step("获取当前账号活动记录"):
            history_list = handle_api_call(init_api.get_user_history_list)
            assert history_list, f"获取账号活动记录失败，返回结果为空"

    @allure.title("获取已读通知")
    def test_read_message(self, init_api):
        with allure.step("获取所有通知列表"):
            message_list = handle_api_call(init_api.get_message_list)
            log.info(f"所有通知列表信息为：{message_list}")

        with allure.step("获取已读通知"):
            read_message = handle_api_call(init_api.get_read_message)
            log.info(f"已读通知列表为：{read_message}")

    @allure.title("通知配置")
    def test_message_config(self, init_api):
        with allure.step("读取当前通知配置"):
            message_config = handle_api_call(init_api.get_message_config)
            log.info(f"当前通知配置为：{message_config}")

        with allure.step("更改通知配置"):
            handle_api_call(init_api.set_message_config)
            time.sleep(0.5)

        with allure.step("再次读取通知配置"):
            new_message_config = handle_api_call(init_api.get_message_config)
            assert new_message_config != message_config, f"更改通知配置失败，预期通知配置：{message_config}，实际通知配置：{new_message_config}"

    @allure.title("清理通知")
    def test_clean_message(self, init_api):
        with allure.step("获取通知列表"):
            message_list = handle_api_call(init_api.get_message_list)
            log.info(f"当前通知列表信息为：{message_list}")

        with allure.step("清除通知"):
            handle_api_call(init_api.clean_message)
            time.sleep(0.5)

        with allure.step("再次获取通知列表"):
            new_message_list = handle_api_call(init_api.get_message_list)
            assert len(new_message_list) == 0, f"清除通知失败，预期通知列表为空，实际通知列表长度为：{len(new_message_list)}"

    @allure.title("桌面搜索功能检查")
    def test_desktop_search(self,init_api):
        with allure.step("更改语言为英文"):
            handle_api_call(init_api.set_user_language, 'en-US')
            time.sleep(5)

        with allure.step("搜索应用中心"):
            app_names = ["com.ugreen.help_server", "com.ugreen.pro.app", "com.ugreen.search_serv.search"]
            try:
                result = handle_api_call(init_api.desktop_search, 'App Center')
                total_count = 0
                for app_name in app_names:
                    if app_name in result:
                        total_count += result[app_name].get('total', 0)
                    else:
                        log.warning(f"应用 {app_name} 在搜索结果中不存在，可能影响最终结果判断")
                assert total_count != 0, f"搜索结果为空，预期搜索结果不为空"
            except KeyError as ke:
                log.error(f"在获取搜索结果数据时出现键值错误，可能是返回结果格式不符合预期，异常信息: {ke}")
                raise
            except Exception as e:
                log.error(f"在执行桌面搜索功能测试过程中出现其他异常，异常信息: {e}")
                raise

        with allure.step("搜索应用中心123"):
            try:
                result = handle_api_call(init_api.desktop_search, 'App Center123')
                total_count = 0
                for app_name in app_names:
                    if app_name in result:
                        total_count += result[app_name].get('total', 0)
                    else:
                        log.warning(f"应用 {app_name} 在搜索结果中不存在，可能影响最终结果判断")
                assert total_count == 0, f"搜索结果不为空，预期搜索结果为空"
            except KeyError as ke:
                log.error(f"在获取搜索结果数据时出现键值错误，可能是返回结果格式不符合预期，异常信息: {ke}")
                raise
            except Exception as e:
                log.error(f"在执行桌面搜索功能测试过程中出现其他异常，异常信息: {e}")
                raise

    @allure.title("更换用户语言")
    def test_change_language(self, init_api):
        with allure.step("获取当前语言信息"):
            language = handle_api_call(init_api.get_user_language)
            log.info(f"更改前的语言信息为：{language}")

        with allure.step("设置语言信息"):
            language_list = ['zh-CN', 'en-US', 'ja-JP', 'de-DE']
            language_list = handle_api_call(init_api.get_language_list)
            set_language = language_list[random.randint(1, 3)].get('key')
            handle_api_call(init_api.set_user_language, set_language)

        with allure.step("再次获取当前语言信息"):
            new_language = handle_api_call(init_api.get_user_language)
            assert new_language == set_language, f"更换语言失败，预期语言：{set_language}，实际语言：{new_language}"

        with allure.step("恢复语言为中文"):
            handle_api_call(init_api.set_user_language, 'zh-CN')
            time.sleep(3)

    @allure.title("更换壁纸")
    def test_change_wallpaper(self,init_api):
        with allure.step("获取默认壁纸列表"):
            wallpaper_list = handle_api_call(init_api.get_wallpaper_list)
            bg_path = wallpaper_list[random.randint(1,10)]
            set_picture_result = handle_api_call(init_api.get_wallpaper_stream,bg_path)
            set_picture_follow = set_picture_result.content

        with allure.step("设置用户壁纸图片"):
            handle_api_call(init_api.change_user_wallpaper,bg_path=bg_path)
            time.sleep(3)

        with allure.step("获取更改后的壁纸"):
            new_result = handle_api_call(init_api.get_user_wallpaper)
            new_picture_follow = new_result.content
            # TODO  断言需要更改，有可能是一样的
            # assert new_picture_follow == set_picture_follow, f"更换壁纸失败，预期壁纸：{set_picture_follow}，实际壁纸列表：{new_picture_follow}"


    @allure.title("更换用户日期与时间格式")
    def test_data_time(self, init_api):
        with allure.step("获取当前配置信息"):
            config_info = handle_api_call(init_api.get_time_config)
            time.sleep(1)
            data_format = config_info.get('date_format')
            time_format = config_info.get('time_format')
            log.info(f"更改前的日期与时间格式为：{data_format}，{time_format}")

        with allure.step("设置日期与时间格式信息"):
            data_format_list = ['YYYY/MM/dd', 'MM/dd/YYYY', 'dd/MM/YYYY', 'YYYY.MM.dd','MM.dd.YYYY','dd.MM.YYYY','YYYY-MM-dd','MM-dd-YYYY','dd-MM-YYYY']
            time_format_list = ['12', '24']
            set_data_format = data_format_list[random.randint(0, 8)]
            set_time_format = time_format_list[random.randint(0, 1)]
            handle_api_call(init_api.set_time_config, date_format=set_data_format, time_format=set_time_format)

        with allure.step("再次获取配置信息"):
            time.sleep(5)
            config_info = handle_api_call(init_api.get_time_config)
            new_data_format = config_info.get('date_format')
            new_time_format = config_info.get('time_format')
            assert new_data_format == set_data_format, f"更换日期格式失败，预期日期格式：{set_data_format}，实际日期格式：{new_data_format}"
            assert new_time_format == set_time_format, f"更换时间格式失败，预期时间格式：{set_time_format}，实际时间格式：{new_time_format}"

    @allure.title("更换用户头像")
    def test_change_user_headpic(self, init_api):
        with allure.step("获取当前用户uid信息"):
            user_name = config.read_config_ini('user', 'user_name')
            uid = handle_api_call(init_api.get_user_uid,user_name)
            log.info(f"当前用户uid信息为：{uid}")

        with allure.step("获取当前用户头像信息"):
            headpic = handle_api_call(init_api.get_user_headpic,uid)
            content = headpic.content

        with allure.step("获取默认头像列表"):
            headpic_list = handle_api_call(init_api.get_user_headpic_list)
            set_headpic = headpic_list[random.randint(1,20)]
            result = handle_api_call(init_api.get_headpic_stream,set_headpic)
            set_content = result.content

        with allure.step("更换用户头像"):
            handle_api_call(init_api.change_user_headpic, uid, icon = set_headpic)
            time.sleep(5)

        with allure.step("再次获取用户头像信息"):
            new_headpic = handle_api_call(init_api.get_user_headpic,uid)
            new_content = new_headpic.content
            assert new_content == set_content, f"更换头像失败，预期头像：{set_content}，实际头像：{new_headpic}"

    @allure.title("更换用户密码")
    def test_change_user_password(self, api,init_api):
        with allure.step("获取当前用户uid信息"):
            host_name = config.read_config_ini('envHost', 'hostname')
            user_name = config.read_config_ini('user', 'user_name')
            raw_password = config.read_config_ini('user', 'user_pwd')
            uid = handle_api_call(init_api.get_user_uid, user_name)
            log.info(f"当前用户uid信息为：{uid}")

        with allure.step("获取Ras_Token"):
            Ras_Token = handle_api_call(api.general_verify_check, host_name,username=user_name)
            log.info(f"获取Ras_Token为：{Ras_Token}")

        with allure.step("密码处理"):
            password = handle_api_call(api.data_encrypt.rsa_passwd,Ras_Token, raw_password)
            new_raw_password = Fake.generate_password()
            new_password = handle_api_call(api.data_encrypt.rsa_passwd, Ras_Token, new_raw_password)

        with allure.step("更换用户密码"):
            handle_api_call(init_api.change_user_password, uid, new_password,password)
            time.sleep(0.5)
            config.set_config_ini('user','user_pwd',new_raw_password)

        with allure.step("使用新密码登录"):
            host_name = config.read_config_ini('envHost', 'hostname')
            Ras_Token = handle_api_call(api.general_verify_check, host_name)
            handle_api_call(api.general_login, host_name,Ras_Token,raw_password=new_raw_password)

        with allure.step("恢复初始密码"):
            handle_api_call(init_api.change_user_password, uid, password,new_password)
            time.sleep(0.5)
            config.set_config_ini('user','user_pwd',raw_password)

    @allure.title("使用普通账号登录")
    def test_login_ordinary(self, api):
        with allure.step("获取普通账号信息"):
            host_name = config.read_config_ini('envHost', 'hostname')
            user_name = config.read_config_ini('user2', 'user_name')
            password = config.read_config_ini('user2', 'user_pwd')
            uid = config.read_config_ini('user2', 'uid')

        with allure.step("使用普通账号获取Rsa_Token"):
            Ras_Token = handle_api_call(api.general_verify_check, host_name, username=user_name)
            log.info(f"获取Ras_Token为：{Ras_Token}")

        with allure.step("使用普通账号登录"):
            result = handle_api_call(api.general_login, host_name, Ras_Token, username=user_name,raw_password=password)
            assert result.get('username') == user_name
            assert result.get('uid') == int(uid)





















